package com.zeyu.soc.log.spi.impl;

import java.io.IOException;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.NotFoundException;

import com.zeyu.soc.log.spi.TransformDescriptor;
import com.zeyu.soc.log.spi.TransformHandler;

public class InsertLogBeforeHandler implements TransformHandler {

	// ================================================================
	// Constants
	// ================================================================

	// ================================================================
	// Fields
	// ================================================================

	// ================================================================
	// Constructors
	// ================================================================

	// ================================================================
	// Methods from/for super Interfaces or SuperClass
	// ================================================================

	@Override
	public boolean canHandler(TransformDescriptor injectDescriptor) {
		return InsertLogBeforeDescriptor.class.isAssignableFrom(injectDescriptor.getClass());
	}

	@Override
	public byte[] transform(TransformDescriptor injectDescriptor) {
		InsertLogBeforeDescriptor descriptor = (InsertLogBeforeDescriptor) injectDescriptor;
		System.out.println("###" + descriptor.getNeedInjectClassName());
		System.out.println("###" + descriptor.getMethodName());
		System.out.println("###" + descriptor.getLogCode());
		try {
			CtClass cc = ClassPool.getDefault().get(descriptor.getNeedInjectClassName());
			cc.defrost();

			CtMethod m = cc.getDeclaredMethod(descriptor.getMethodName());
			m.insertBefore(descriptor.getLogCode());
			return cc.toBytecode();
		} catch (NotFoundException e) {
			e.printStackTrace();
		} catch (CannotCompileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	// ================================================================
	// Public or Protected Methods
	// ================================================================

	// ================================================================
	// Getter & Setter
	// ================================================================

	// ================================================================
	// Private Methods
	// ================================================================

	// ================================================================
	// Inner or Anonymous Class
	// ================================================================

	// ================================================================
	// Test Methods
	// ================================================================
}
